package com.edu.app.controller.wechat;

import com.edu.app.bean.core.SysTenant;
import com.edu.app.model.wechat.WechatConfig;
import com.edu.app.model.wechat.WxErrorException;
import com.edu.app.model.wechat.msg.WechatTemplateMsg;
import com.edu.app.service.impl.wechat.msgroute.WxMpMessageRouter;
import com.edu.app.service.sys.wechat.*;
import com.edu.app.threadlocal.TenantContext;
import com.edu.app.util.JWTUtil;
import com.edu.app.util.json.JsonUtil;
import com.edu.app.util.xml.MessageUtil;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@Controller
@RequestMapping("api/wechat")
public class WechatController implements ApplicationContextAware {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private ApplicationContext applicationContext;
    @Autowired
    private WechatTemplateMsgService wechatTemplateMsgService;

    @Autowired
    private WechatQRCodeService wechatQRCodeService;

    @Autowired
    private WechatUserService wechatUserService;

    @Autowired
    private WechatMenuService wechatMenuService;


    @Autowired
    private WechatBaseService wechatBaseService;

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private WxMpMessageRouter wechatMsgRouter;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        this.applicationContext = applicationContext;

        logger.info("ApplicationContext配置成功,applicationContext对象："+this.applicationContext);

    }


    @RequestMapping(value="/templatemsg", method= RequestMethod.POST)
    @ResponseBody
    public String sendTemplate(@RequestParam("userOpenId")String userOpenId){
        //TemplateMsgResult templateMsgResult = null;
        String response = null;
        TreeMap<String,TreeMap<String,String>> params = new TreeMap<String,TreeMap<String,String>>();
        //根据具体模板参数组装
        /*params.put("first",   WechatTemplateMsg.item("您好，您已成为微信某某店会员。", "#000000"));
        params.put("cardNumber",WechatTemplateMsg.item("87457", "#000000"));
        params.put("address",WechatTemplateMsg.item("朝阳区北苑", "#000000"));
        params.put("VIPName",WechatTemplateMsg.item("xxx", "#000000"));
        params.put("VIPPhone",WechatTemplateMsg.item("1111111111", "#000000"));
        params.put("expDate",  WechatTemplateMsg.item("2019.09.30", "#000000"));
        params.put("remark",  WechatTemplateMsg.item("多多关注！", "#000000"));*/

        params.put("first", WechatTemplateMsg.item("果果小朋友的课程将在15分钟后开始", "#1296db"));
        params.put("keyword1", WechatTemplateMsg.item("右脑课", "#000000"));
        params.put("keyword2", WechatTemplateMsg.item("2015-07-15 星期三 10:00-11:00", "#000000"));
        params.put("keyword3", WechatTemplateMsg.item("引领右脑朝阳中心北苑店", "#000000"));
        params.put("remark", WechatTemplateMsg.item("请提前做好备课工作", "#1296db"));

        WechatTemplateMsg wechatTemplateMsg = new WechatTemplateMsg();
        wechatTemplateMsg.setTemplate_id("EHOzB7rGr2sjL5keh9SJdzMwzqtr95mRsDTuQuQ44F8");
        wechatTemplateMsg.setTouser(userOpenId);
        wechatTemplateMsg.setData(params);
        wechatTemplateMsg.setUrl("www.edumavin.com");
        String data = null;
        try {
            data = JsonUtil.toJson(wechatTemplateMsg);
            response =  wechatTemplateMsgService.sendTemplate(data);
        }catch(JsonProcessingException e){

        }catch(WxErrorException e)
        {

        }

        return response;
        //return templateMsgResult;
    }

    @RequestMapping(value="/menu", method= RequestMethod.POST)
    @ResponseBody
    public String createMenu(@RequestParam("menu")String menujson){
        //TemplateMsgResult templateMsgResult = null;
        String response = null;
        TreeMap<String,Object> menus = new TreeMap<String,Object>();
        ArrayList<Object> menuList = new ArrayList<>();
        menus.put("button",menuList );

        TreeMap<String,String> menu = new TreeMap<>();
        menu.put("type","view");
        menu.put("name","进入多招");
        menu.put("url","http://www.edumavin.com");

        menuList.add(menu);

        String data = null;
        try {
            data = JsonUtil.toJson(menus);
            response =  wechatMenuService.menuCreate(data);
        }catch(JsonProcessingException e){

        }catch(WxErrorException e)
        {

        }

        return response;
        //return templateMsgResult;
    }

    @RequestMapping(value="/users", method= RequestMethod.GET)
    @ResponseBody
    public String getUserList(){
        String data = null;
        try {
            data =  wechatUserService.userList(null);
        }catch(WxErrorException e){

        }
        return data;
    }

    @RequestMapping(value="/tmpqrcode", method= RequestMethod.GET)
    @ResponseBody
    @RequiresAuthentication
    public String getBindQrCode(@RequestHeader("Authorization") String token){
        String data = null;
        try {
            //generate scence value
            String username = JWTUtil.getUsername(token);
            SysTenant tenant =  (SysTenant) TenantContext.getCurrentTenant();
            StringBuffer scenceStr = new StringBuffer();
            scenceStr.append(tenant.getId());
            scenceStr.append("_");
            scenceStr.append(username);
            data =  wechatQRCodeService.qrCodeCreateTmpTicket(scenceStr.toString(),604800);

            Map<String,String> map = JsonUtil.fromJson(data,Map.class);

            String ticket = map.get("ticket");
            String qrUrl = wechatQRCodeService.qrCodePictureUrl(ticket);
            map.put("qrurl",qrUrl);
            data = JsonUtil.toJson(map);

        }catch(WxErrorException e){

        }catch(IOException ioe){

        }
        return data;
    }

    @RequestMapping(value="/server", method= RequestMethod.GET)
    @ResponseBody
    public String WeChatGetInterface(HttpServletRequest request, HttpServletResponse response){

        System.out.println("-------------验证微信服务号信息开始----------");
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

        logger.info("signature is :"+signature+"timestamp is"+timestamp+"nonce is :"+nonce);
        if (wechatBaseService.checkSignature(wechatConfig.getToken(), timestamp, nonce,signature)){
            System.out.println("-----------验证微信服务号结束------------");
            return echostr;
        }else {
            logger.warn("不是微信服务器发过来的请求，请小心！");
            return "";
        }
    }


    @RequestMapping(value="/server", method= RequestMethod.POST)
    @ResponseBody
    public void WeChatPostInterface(HttpServletRequest request, HttpServletResponse response) throws IOException {

        response.setCharacterEncoding("utf-8");


        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");

        Map<String,String> msgMap  = MessageUtil.xmlToMap(request.getInputStream());

        String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ?
                "raw" :
                request.getParameter("encrypt_type");

        if ("raw".equals(encryptType)) {
            // 明文传输的消息
            //WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
            //WxMpXmlOutMessage outMessage = this.wxMpMessageRouter.route(inMessage);
            //if (outMessage != null) {
            //    response.getWriter().write(outMessage.toXml());
           // }
            Map<String,Object> contextMap = new HashMap<String,Object>();
            contextMap.put("appContext",this.applicationContext);

            Map<String,String> retmap = wechatMsgRouter.route(msgMap,contextMap,null);
            return;
        }

        if ("aes".equals(encryptType)) {
            // 是aes加密的消息
            String msgSignature = request.getParameter("msg_signature");
           // WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), this.wxMpConfigStorage, timestamp, nonce, msgSignature);
           // WxMpXmlOutMessage outMessage = this.wxMpMessageRouter.route(inMessage);
           // response.getWriter().write(outMessage.toEncryptedXml(this.wxMpConfigStorage));
            return;
        }

        response.getWriter().println("不可识别的加密类型");
    }

    @RequestMapping(value="/page/oauth2", method= RequestMethod.GET)
    public void wechatPageOAuth(HttpServletRequest request, HttpServletResponse response) {
        String code     = request.getParameter("code");
        String state    = request.getParameter("state");
        String resjson  = wechatBaseService.getAuthAccessToken(code,wechatConfig.getAppid(),wechatConfig.getAppsecret());

        StringBuffer urlbf = new StringBuffer();
        urlbf.append("window.location.replace('");
        urlbf.append(state);
        urlbf.append("#");
        try {
            Map<String,Object> resMap = JsonUtil.fromJson(resjson, java.util.Map.class);
            String openId = (String) resMap.get("openid");
            urlbf.append("?openId=");
            urlbf.append(openId);
            urlbf.append("')");
            PrintWriter out=response.getWriter();
            out.println("<script>");
            out.print( urlbf.toString());
            out.println("</script>");
        }
        catch(IOException ioe){
              ioe.printStackTrace();
        }

    }
 }